package main

import (
	"fmt"
	"net"
	"strings"
)

type User struct {
	Name string
	Addr string
	C chan string
	conn net.Conn

	server *Server
}

func NewUser(name string, conn net.Conn, server *Server) *User {
	userAddr := conn.RemoteAddr().String()

	user := &User {
		Name: name,
		Addr: userAddr,
		C: make(chan string),
		conn: conn,
		server: server,
	}

	go user.ListenChan()

	return user
}

func (this *User) SendMsg(msg string) {
	this.conn.Write([]byte(msg+"\n"))
}

// watch cur user channel, when there is a message, transfer to the client
func (this *User) ListenChan() {
	for {
		msg := <-this.C
		this.SendMsg(msg)
	}
}

func (this *User) Online() {
	// put user into onlinemap
	this.server.mapLock.Lock()
	this.server.OnlineMap[this.Name] = this
	this.server.mapLock.Unlock()

	// broadcast on line msg
	this.server.Broadcast(this, "已上线")
}

func (this *User) OffLine() {
	// del user from onlinemap
	this.server.mapLock.Lock()
	delete(this.server.OnlineMap, this.Name)
	this.server.mapLock.Unlock()

	this.server.Broadcast(this, "下线")
}

func (this *User) DoMessage(msg string) {
	if msg == "ls" {
		this.server.mapLock.RLock()
		for _, cli := range this.server.OnlineMap {
			this.SendMsg(cli.Name)
		}
		this.server.mapLock.RUnlock()
	} else if len(msg) > 4 && msg[:3] == "to|" {
		split := strings.Split(msg, "|")
		this.server.mapLock.RLock()
		recipient := this.server.OnlineMap[split[1]]
		this.server.mapLock.RUnlock()

		if recipient == nil {
			this.SendMsg("对不起，没有这号人")
			return
		}
		if len(split) == 3 {
			msg := fmt.Sprintf("[%s]%s对你说：\n%s", this.Name, this.Addr, split[2])
			recipient.SendMsg(msg)
		} else {
			msg := fmt.Sprintf(
				"[%s]%s对你说：\n%s", this.Name, this.Addr, strings.Join(split[2:], "|"))
			recipient.SendMsg(msg)
		}
	} else {
		this.server.Broadcast(this, msg)
	}
}
	
